package utils

import (
	"flag"
	"log"

	"github.com/nacos-group/nacos-sdk-go/common/constant"
	"go.uber.org/zap"
)

/*
 +----------------------------------------------------------------------
 + Title        : 初始化项目
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2020-01-06
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : 初始化项目
 +----------------------------------------------------------------------
*/

// 运行环境
var Env string

// Bug模式
var BugMode string

// 服务名称
var ServiceName string

// 服务版本
var ServiceVersion string

// 服务地址
var ServiceHost string

// 服务端口
var ServicePort int

// http服务地址
var HttpHost string

// http服务端口
var HttpPort int

// ------------------ 服务注册与发现、配置中心开始 ------------------
// 服务发现
var ServiceDiscovery string

// 服务注册
var ServiceRegister string

// 配置中心
var ConfigCenter string

// nacos 配置
type NacosConfig struct {
	Addrs               string
	NameSpaceId         string
	Username            string
	Password            string
	TimeoutMs           int
	NotLoadCacheAtAtart bool
	LogDir              string
	CacheDir            string
	LogLevel            string
	ContextPath         string
	Group               string
	ClusterName         string
}

// nacos 配置实例
var NacosCfg NacosConfig

// nacos 客户配置
var NacosClientConfig constant.ClientConfig

// nacos 服务配置
var NacosServerConfigs []constant.ServerConfig

// ------------------ 服务注册与发现、配置中心结束 ------------------

// --------------------- Zap 日志相关参数开始 ----------------------
var ZapLoggerMaxSize int
var ZapLoggerMaxBackups int
var ZapLoggerMaxAge int
var ZapLoggerCompress bool
var ZapLog *zap.Logger

// --------------------- Zap 日志相关参数结束 ----------------------

// ------------------------- jaeger 开始 --------------------------
var JaegerAddr string

// ------------------------- jaeger 结束 --------------------------

// ------------------------- 配置中心开始 --------------------------
// 配置中心 mysql 名称
var MySqlConfigCenter string

// 配置中心 redis 名称
var RedisConfigCenter string

// 配置中心 mongo 名称
var MongoConfigCenter string

// 配置中心 es 名称
var EsConfigCenter string

// 配置中心 rabbit 名称
var RabbitConfigCenter string

// ------------------------- 配置中心结束 --------------------------

func init() {

	// 设置日志标志：添加 Llongfile 或 Lshortfile
	log.SetFlags(log.LstdFlags | log.Llongfile) // 完整路径
	// 或者
	// log.SetFlags(log.LstdFlags | log.Lshortfile) // 短路径

	appConfig, err := GetConfig("app", "yml")
	if err != nil {
		log.Fatalf("Failed to read app config: %v", err)
	}

	// 运行环境
	flag.StringVar(&Env, "env", "dev", "运行环境")
	flag.Parse()

	log.Println("current environment: ", Env)

	// Bug模式
	BugMode = appConfig.GetString("bug_mode")

	// 获取服务名称
	ServiceName = appConfig.GetString("service_name")

	// 获取服务版本
	ServiceVersion = appConfig.GetString("service_version")

	// 获取服务地址
	ServiceHost = appConfig.GetString(Env + ".service_host")

	// 获取服务端口
	ServicePort = appConfig.GetInt(Env + ".service_port")

	// 获取http服务地址
	HttpHost = appConfig.GetString(Env + ".http_host")

	// 获取http服务端口
	HttpPort = appConfig.GetInt(Env + ".http_port")

	// 服务注册
	ServiceRegister = appConfig.GetString(Env + ".service_register")

	// 服务发现
	ServiceDiscovery = appConfig.GetString(Env + ".service_discovery")

	// 配置中心
	ConfigCenter = appConfig.GetString(Env + ".config_center")

	// 配置中心 mysql 名称
	MySqlConfigCenter = appConfig.GetString("mysql_config_center")

	// 配置中心 redis 名称
	RedisConfigCenter = appConfig.GetString("redis_config_center")

	// 配置中心 mongo 名称
	MongoConfigCenter = appConfig.GetString("mongo_config_center")

	// 配置中心 es 名称
	EsConfigCenter = appConfig.GetString("es_config_center")

	// 配置中心 rabbit 名称
	RabbitConfigCenter = appConfig.GetString("rabbit_config_center")

	// ----------------------- zap 日志相关参数开始 -----------------------
	ZapLoggerMaxSize = appConfig.GetInt(Env + ".zlogger_maxsize")
	ZapLoggerMaxBackups = appConfig.GetInt(Env + ".zlogger_max_backups")
	ZapLoggerMaxAge = appConfig.GetInt(Env + ".zlogger_max_age")
	ZapLoggerCompress = appConfig.GetBool(Env + ".zlogger_compress")
	// ----------------------- zap 日志相关参数结束 -----------------------

	// JaegerAddr
	JaegerAddr = appConfig.GetString(Env + ".jaeger_addr")
}

// 初始化 nacos 配置
func InitNacosConfig() {
	if NacosCfg.Addrs == "" {
		// 读取nacos配置文件
		cfg, err := GetConfig("nacos", "yml")
		if err != nil {
			log.Fatalf("Failed to read nacos config: %v", err)
		}

		NacosCfg.Addrs = cfg.GetString(Env + ".addrs")
		NacosCfg.NameSpaceId = cfg.GetString(Env + ".name_space_id")
		NacosCfg.Username = cfg.GetString(Env + ".username")
		NacosCfg.Password = cfg.GetString(Env + ".password")
		NacosCfg.TimeoutMs = cfg.GetInt(Env + ".timeout_ms")
		NacosCfg.NotLoadCacheAtAtart = cfg.GetBool(Env + ".not_load_cache_at_start")
		NacosCfg.LogDir = cfg.GetString(Env + ".log_dir")
		NacosCfg.CacheDir = cfg.GetString(Env + ".cache_dir")
		NacosCfg.LogLevel = cfg.GetString(Env + ".log_level")
		NacosCfg.ContextPath = cfg.GetString(Env + ".context_path")
		NacosCfg.Group = cfg.GetString(Env + ".group")
		NacosCfg.ClusterName = cfg.GetString(Env + ".cluster_name")
	}
}

/**
 * 初始化配置中心
 *
 * @param string configName -----------------------------------必传
 * @param any ConfigStruct ------------------------------------必传
 * @author huwl
 */
func InitConfigCenter(configName string, ConfigStruct any) {
	switch ConfigCenter {
	case "nacos":
		// 初始化配置
		InitNacosConfig()

		// 创建NACOS配置中心
		cc, err := NewNacosConfigCenter()
		if err != nil {
			log.Fatalf("Failed to create NacosConfigCenter: %v", err)
		}

		// 获取配置数据
		cc.GetConfigData(configName, ConfigStruct, "DEFAULT_GROUP")

	case "consul":
		// 读取CONSUL配置文件
		consulConf, err := GetConfig("consul", "yml")
		if err != nil {
			log.Fatalf("Failed to read consul config: %v", err)
		}

		// 创建CONSUL配置中心
		// 获取配置信息：key格式Env+"/"+configName => /micro/config/dev/mysql_config
		cc, err := NewConsulConfigCenter(
			consulConf.GetString(Env+".addrs"),
			consulConf.GetString(Env+".token"),
			consulConf.GetString(Env+".prefix")+"/"+configName,
		)
		if err != nil {
			log.Fatalf("Failed to read consul config: %v", err)
		}

		// 获取ETCD配置数据
		cc.GetConfigData(ConfigStruct)

	case "etcd":
		// 读取ETCD配置文件
		etcdConfig, err := GetConfig("etcd", "yml")
		if err != nil {
			log.Fatalf("Failed to read etcd config: %v", err)
		}

		// 创建ETCD配置中心
		cc, err := NewEtcdConfigCenter(
			etcdConfig.GetStringSlice(Env+".addrs"),
			etcdConfig.GetString(Env+".username"),
			etcdConfig.GetString(Env+".password"),
			etcdConfig.GetString(Env+".config_prefix")+"/"+configName,
		)
		if err != nil {
			log.Fatalf("Failed to create EtcdConfigCenter: %v", err)
		}

		// 获取ETCD配置数据
		cc.GetConfigData(ConfigStruct)

		// 监控ETCD配置
		cc.WatchConfig(configName, ConfigStruct)
	}
}
